/*
 * Selling Partner API for Replenishment
 *
 * The Selling Partner API for Replenishment (Replenishment API) provides programmatic access to replenishment program metrics and offers. These programs provide recurring delivery of any replenishable item at a frequency chosen by the customer.  The Replenishment API is available worldwide wherever Amazon Subscribe & Save is available or is supported. The API is available to vendors and FBA selling partners.
 *
 * The version of the OpenAPI document: 2022-11-07
 * Generated by: https://github.com/openapitools/openapi-generator.git
 */


using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.IO;
using System.Runtime.Serialization;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System.ComponentModel.DataAnnotations;
using OpenAPIDateConverter = software.amzn.spapi.Client.OpenAPIDateConverter;

namespace software.amzn.spapi.Model.replenishment.v2022_11_07
{
    /// <summary>
    /// An object which contains offer metrics.
    /// </summary>
    [DataContract(Name = "ListOfferMetricsResponseOffer")]
    public partial class ListOfferMetricsResponseOffer : IValidatableObject
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="ListOfferMetricsResponseOffer" /> class.
        /// </summary>
        /// <param name="asin">The Amazon Standard Identification Number (ASIN)..</param>
        /// <param name="notDeliveredDueToOOS">The percentage of items that were not shipped out of the total shipped units over a period of time due to being out of stock. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="totalSubscriptionsRevenue">The revenue generated from subscriptions over a period of time. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="shippedSubscriptionUnits">The number of units shipped to the subscribers over a period of time. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="activeSubscriptions">The number of active subscriptions present at the end of the period. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="revenuePenetration">The percentage of total program revenue out of total product revenue. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="lostRevenueDueToOOS">The revenue that would have been generated had there not been out of stock. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="couponsRevenuePenetration">The percentage of revenue from ASINs with coupons out of total revenue from all ASINs. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="shareOfCouponSubscriptions">The percentage of new subscriptions acquired through coupons. Applicable to PERFORMANCE timePeriodType..</param>
        /// <param name="next30DayTotalSubscriptionsRevenue">The forecasted total subscription revenue for the next 30 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="next60DayTotalSubscriptionsRevenue">The forecasted total subscription revenue for the next 60 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="next90DayTotalSubscriptionsRevenue">The forecasted total subscription revenue for the next 90 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="next30DayShippedSubscriptionUnits">The forecasted shipped subscription units for the next 30 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="next60DayShippedSubscriptionUnits">The forecasted shipped subscription units for the next 60 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="next90DayShippedSubscriptionUnits">The forecasted shipped subscription units for the next 90 days. Applicable to FORECAST timePeriodType..</param>
        /// <param name="timeInterval">timeInterval.</param>
        /// <param name="currencyCode">The currency code in ISO 4217 format..</param>
        public ListOfferMetricsResponseOffer(string asin = default(string), double notDeliveredDueToOOS = default(double), double totalSubscriptionsRevenue = default(double), decimal shippedSubscriptionUnits = default(decimal), decimal activeSubscriptions = default(decimal), double revenuePenetration = default(double), double lostRevenueDueToOOS = default(double), double couponsRevenuePenetration = default(double), double shareOfCouponSubscriptions = default(double), double next30DayTotalSubscriptionsRevenue = default(double), double next60DayTotalSubscriptionsRevenue = default(double), double next90DayTotalSubscriptionsRevenue = default(double), decimal next30DayShippedSubscriptionUnits = default(decimal), decimal next60DayShippedSubscriptionUnits = default(decimal), decimal next90DayShippedSubscriptionUnits = default(decimal), TimeInterval timeInterval = default(TimeInterval), string currencyCode = default(string))
        {
            this.Asin = asin;
            this.NotDeliveredDueToOOS = notDeliveredDueToOOS;
            this.TotalSubscriptionsRevenue = totalSubscriptionsRevenue;
            this.ShippedSubscriptionUnits = shippedSubscriptionUnits;
            this.ActiveSubscriptions = activeSubscriptions;
            this.RevenuePenetration = revenuePenetration;
            this.LostRevenueDueToOOS = lostRevenueDueToOOS;
            this.CouponsRevenuePenetration = couponsRevenuePenetration;
            this.ShareOfCouponSubscriptions = shareOfCouponSubscriptions;
            this.Next30DayTotalSubscriptionsRevenue = next30DayTotalSubscriptionsRevenue;
            this.Next60DayTotalSubscriptionsRevenue = next60DayTotalSubscriptionsRevenue;
            this.Next90DayTotalSubscriptionsRevenue = next90DayTotalSubscriptionsRevenue;
            this.Next30DayShippedSubscriptionUnits = next30DayShippedSubscriptionUnits;
            this.Next60DayShippedSubscriptionUnits = next60DayShippedSubscriptionUnits;
            this.Next90DayShippedSubscriptionUnits = next90DayShippedSubscriptionUnits;
            this.TimeInterval = timeInterval;
            this.CurrencyCode = currencyCode;
        }

        /// <summary>
        /// The Amazon Standard Identification Number (ASIN).
        /// </summary>
        /// <value>The Amazon Standard Identification Number (ASIN).</value>
        [DataMember(Name = "asin", EmitDefaultValue = false)]
        public string Asin { get; set; }

        /// <summary>
        /// The percentage of items that were not shipped out of the total shipped units over a period of time due to being out of stock. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The percentage of items that were not shipped out of the total shipped units over a period of time due to being out of stock. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "notDeliveredDueToOOS", EmitDefaultValue = false)]
        public double NotDeliveredDueToOOS { get; set; }

        /// <summary>
        /// The revenue generated from subscriptions over a period of time. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The revenue generated from subscriptions over a period of time. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "totalSubscriptionsRevenue", EmitDefaultValue = false)]
        public double TotalSubscriptionsRevenue { get; set; }

        /// <summary>
        /// The number of units shipped to the subscribers over a period of time. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The number of units shipped to the subscribers over a period of time. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "shippedSubscriptionUnits", EmitDefaultValue = false)]
        public decimal ShippedSubscriptionUnits { get; set; }

        /// <summary>
        /// The number of active subscriptions present at the end of the period. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The number of active subscriptions present at the end of the period. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "activeSubscriptions", EmitDefaultValue = false)]
        public decimal ActiveSubscriptions { get; set; }

        /// <summary>
        /// The percentage of total program revenue out of total product revenue. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The percentage of total program revenue out of total product revenue. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "revenuePenetration", EmitDefaultValue = false)]
        public double RevenuePenetration { get; set; }

        /// <summary>
        /// The revenue that would have been generated had there not been out of stock. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The revenue that would have been generated had there not been out of stock. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "lostRevenueDueToOOS", EmitDefaultValue = false)]
        public double LostRevenueDueToOOS { get; set; }

        /// <summary>
        /// The percentage of revenue from ASINs with coupons out of total revenue from all ASINs. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The percentage of revenue from ASINs with coupons out of total revenue from all ASINs. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "couponsRevenuePenetration", EmitDefaultValue = false)]
        public double CouponsRevenuePenetration { get; set; }

        /// <summary>
        /// The percentage of new subscriptions acquired through coupons. Applicable to PERFORMANCE timePeriodType.
        /// </summary>
        /// <value>The percentage of new subscriptions acquired through coupons. Applicable to PERFORMANCE timePeriodType.</value>
        [DataMember(Name = "shareOfCouponSubscriptions", EmitDefaultValue = false)]
        public double ShareOfCouponSubscriptions { get; set; }

        /// <summary>
        /// The forecasted total subscription revenue for the next 30 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted total subscription revenue for the next 30 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next30DayTotalSubscriptionsRevenue", EmitDefaultValue = false)]
        public double Next30DayTotalSubscriptionsRevenue { get; set; }

        /// <summary>
        /// The forecasted total subscription revenue for the next 60 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted total subscription revenue for the next 60 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next60DayTotalSubscriptionsRevenue", EmitDefaultValue = false)]
        public double Next60DayTotalSubscriptionsRevenue { get; set; }

        /// <summary>
        /// The forecasted total subscription revenue for the next 90 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted total subscription revenue for the next 90 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next90DayTotalSubscriptionsRevenue", EmitDefaultValue = false)]
        public double Next90DayTotalSubscriptionsRevenue { get; set; }

        /// <summary>
        /// The forecasted shipped subscription units for the next 30 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted shipped subscription units for the next 30 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next30DayShippedSubscriptionUnits", EmitDefaultValue = false)]
        public decimal Next30DayShippedSubscriptionUnits { get; set; }

        /// <summary>
        /// The forecasted shipped subscription units for the next 60 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted shipped subscription units for the next 60 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next60DayShippedSubscriptionUnits", EmitDefaultValue = false)]
        public decimal Next60DayShippedSubscriptionUnits { get; set; }

        /// <summary>
        /// The forecasted shipped subscription units for the next 90 days. Applicable to FORECAST timePeriodType.
        /// </summary>
        /// <value>The forecasted shipped subscription units for the next 90 days. Applicable to FORECAST timePeriodType.</value>
        [DataMember(Name = "next90DayShippedSubscriptionUnits", EmitDefaultValue = false)]
        public decimal Next90DayShippedSubscriptionUnits { get; set; }

        /// <summary>
        /// Gets or Sets TimeInterval
        /// </summary>
        [DataMember(Name = "timeInterval", EmitDefaultValue = false)]
        public TimeInterval TimeInterval { get; set; }

        /// <summary>
        /// The currency code in ISO 4217 format.
        /// </summary>
        /// <value>The currency code in ISO 4217 format.</value>
        [DataMember(Name = "currencyCode", EmitDefaultValue = false)]
        public string CurrencyCode { get; set; }

        /// <summary>
        /// Returns the string presentation of the object
        /// </summary>
        /// <returns>String presentation of the object</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("class ListOfferMetricsResponseOffer {\n");
            sb.Append("  Asin: ").Append(Asin).Append("\n");
            sb.Append("  NotDeliveredDueToOOS: ").Append(NotDeliveredDueToOOS).Append("\n");
            sb.Append("  TotalSubscriptionsRevenue: ").Append(TotalSubscriptionsRevenue).Append("\n");
            sb.Append("  ShippedSubscriptionUnits: ").Append(ShippedSubscriptionUnits).Append("\n");
            sb.Append("  ActiveSubscriptions: ").Append(ActiveSubscriptions).Append("\n");
            sb.Append("  RevenuePenetration: ").Append(RevenuePenetration).Append("\n");
            sb.Append("  LostRevenueDueToOOS: ").Append(LostRevenueDueToOOS).Append("\n");
            sb.Append("  CouponsRevenuePenetration: ").Append(CouponsRevenuePenetration).Append("\n");
            sb.Append("  ShareOfCouponSubscriptions: ").Append(ShareOfCouponSubscriptions).Append("\n");
            sb.Append("  Next30DayTotalSubscriptionsRevenue: ").Append(Next30DayTotalSubscriptionsRevenue).Append("\n");
            sb.Append("  Next60DayTotalSubscriptionsRevenue: ").Append(Next60DayTotalSubscriptionsRevenue).Append("\n");
            sb.Append("  Next90DayTotalSubscriptionsRevenue: ").Append(Next90DayTotalSubscriptionsRevenue).Append("\n");
            sb.Append("  Next30DayShippedSubscriptionUnits: ").Append(Next30DayShippedSubscriptionUnits).Append("\n");
            sb.Append("  Next60DayShippedSubscriptionUnits: ").Append(Next60DayShippedSubscriptionUnits).Append("\n");
            sb.Append("  Next90DayShippedSubscriptionUnits: ").Append(Next90DayShippedSubscriptionUnits).Append("\n");
            sb.Append("  TimeInterval: ").Append(TimeInterval).Append("\n");
            sb.Append("  CurrencyCode: ").Append(CurrencyCode).Append("\n");
            sb.Append("}\n");
            return sb.ToString();
        }

        /// <summary>
        /// Returns the JSON string presentation of the object
        /// </summary>
        /// <returns>JSON string presentation of the object</returns>
        public virtual string ToJson()
        {
            return Newtonsoft.Json.JsonConvert.SerializeObject(this, Newtonsoft.Json.Formatting.Indented);
        }

        /// <summary>
        /// To validate all properties of the instance
        /// </summary>
        /// <param name="validationContext">Validation context</param>
        /// <returns>Validation Result</returns>
        IEnumerable<ValidationResult> IValidatableObject.Validate(ValidationContext validationContext)
        {
            // NotDeliveredDueToOOS (double) maximum
            if (this.NotDeliveredDueToOOS > (double)1E+2)
            {
                yield return new ValidationResult("Invalid value for NotDeliveredDueToOOS, must be a value less than or equal to 1E+2.", new [] { "NotDeliveredDueToOOS" });
            }

            // NotDeliveredDueToOOS (double) minimum
            if (this.NotDeliveredDueToOOS < (double)0)
            {
                yield return new ValidationResult("Invalid value for NotDeliveredDueToOOS, must be a value greater than or equal to 0.", new [] { "NotDeliveredDueToOOS" });
            }

            // TotalSubscriptionsRevenue (double) minimum
            if (this.TotalSubscriptionsRevenue < (double)0)
            {
                yield return new ValidationResult("Invalid value for TotalSubscriptionsRevenue, must be a value greater than or equal to 0.", new [] { "TotalSubscriptionsRevenue" });
            }

            // ShippedSubscriptionUnits (decimal) minimum
            if (this.ShippedSubscriptionUnits < (decimal)0)
            {
                yield return new ValidationResult("Invalid value for ShippedSubscriptionUnits, must be a value greater than or equal to 0.", new [] { "ShippedSubscriptionUnits" });
            }

            // ActiveSubscriptions (decimal) minimum
            if (this.ActiveSubscriptions < (decimal)0)
            {
                yield return new ValidationResult("Invalid value for ActiveSubscriptions, must be a value greater than or equal to 0.", new [] { "ActiveSubscriptions" });
            }

            // RevenuePenetration (double) maximum
            if (this.RevenuePenetration > (double)1E+2)
            {
                yield return new ValidationResult("Invalid value for RevenuePenetration, must be a value less than or equal to 1E+2.", new [] { "RevenuePenetration" });
            }

            // RevenuePenetration (double) minimum
            if (this.RevenuePenetration < (double)0)
            {
                yield return new ValidationResult("Invalid value for RevenuePenetration, must be a value greater than or equal to 0.", new [] { "RevenuePenetration" });
            }

            // LostRevenueDueToOOS (double) minimum
            if (this.LostRevenueDueToOOS < (double)0)
            {
                yield return new ValidationResult("Invalid value for LostRevenueDueToOOS, must be a value greater than or equal to 0.", new [] { "LostRevenueDueToOOS" });
            }

            // CouponsRevenuePenetration (double) maximum
            if (this.CouponsRevenuePenetration > (double)1E+2)
            {
                yield return new ValidationResult("Invalid value for CouponsRevenuePenetration, must be a value less than or equal to 1E+2.", new [] { "CouponsRevenuePenetration" });
            }

            // CouponsRevenuePenetration (double) minimum
            if (this.CouponsRevenuePenetration < (double)0)
            {
                yield return new ValidationResult("Invalid value for CouponsRevenuePenetration, must be a value greater than or equal to 0.", new [] { "CouponsRevenuePenetration" });
            }

            // ShareOfCouponSubscriptions (double) maximum
            if (this.ShareOfCouponSubscriptions > (double)1E+2)
            {
                yield return new ValidationResult("Invalid value for ShareOfCouponSubscriptions, must be a value less than or equal to 1E+2.", new [] { "ShareOfCouponSubscriptions" });
            }

            // ShareOfCouponSubscriptions (double) minimum
            if (this.ShareOfCouponSubscriptions < (double)0)
            {
                yield return new ValidationResult("Invalid value for ShareOfCouponSubscriptions, must be a value greater than or equal to 0.", new [] { "ShareOfCouponSubscriptions" });
            }

            // Next30DayTotalSubscriptionsRevenue (double) minimum
            if (this.Next30DayTotalSubscriptionsRevenue < (double)0)
            {
                yield return new ValidationResult("Invalid value for Next30DayTotalSubscriptionsRevenue, must be a value greater than or equal to 0.", new [] { "Next30DayTotalSubscriptionsRevenue" });
            }

            // Next60DayTotalSubscriptionsRevenue (double) minimum
            if (this.Next60DayTotalSubscriptionsRevenue < (double)0)
            {
                yield return new ValidationResult("Invalid value for Next60DayTotalSubscriptionsRevenue, must be a value greater than or equal to 0.", new [] { "Next60DayTotalSubscriptionsRevenue" });
            }

            // Next90DayTotalSubscriptionsRevenue (double) minimum
            if (this.Next90DayTotalSubscriptionsRevenue < (double)0)
            {
                yield return new ValidationResult("Invalid value for Next90DayTotalSubscriptionsRevenue, must be a value greater than or equal to 0.", new [] { "Next90DayTotalSubscriptionsRevenue" });
            }

            // Next30DayShippedSubscriptionUnits (decimal) minimum
            if (this.Next30DayShippedSubscriptionUnits < (decimal)0)
            {
                yield return new ValidationResult("Invalid value for Next30DayShippedSubscriptionUnits, must be a value greater than or equal to 0.", new [] { "Next30DayShippedSubscriptionUnits" });
            }

            // Next60DayShippedSubscriptionUnits (decimal) minimum
            if (this.Next60DayShippedSubscriptionUnits < (decimal)0)
            {
                yield return new ValidationResult("Invalid value for Next60DayShippedSubscriptionUnits, must be a value greater than or equal to 0.", new [] { "Next60DayShippedSubscriptionUnits" });
            }

            // Next90DayShippedSubscriptionUnits (decimal) minimum
            if (this.Next90DayShippedSubscriptionUnits < (decimal)0)
            {
                yield return new ValidationResult("Invalid value for Next90DayShippedSubscriptionUnits, must be a value greater than or equal to 0.", new [] { "Next90DayShippedSubscriptionUnits" });
            }

            yield break;
        }
    }

}
